<template>
  <Select v-model="select" :placeholder="placeholder" :clearable="clearable"
    :multiple="multiple" :filterable="filterable" @on-open-change="onOpenChange"
    :loading="loading" :disabled="disabled">
    <Option v-for="(d,i) in items" :label="autoLabel?d.text:undefined" :value="d.value"
      :key="i">
      <template v-if="$scopedSlots.default">
        <slot :index="i" :data="d" :datas="items"></slot>
      </template>
      <template v-else>{{ d.text }}</template>
    </Option>
  </Select>
</template>

<script>
import { isFunction } from '_/utils/tools';
export default {
  name: 'DataSelector',
  props: {
    value: [Array, Number, String],
    params: {
      type: Object,
      default() {
        return {};
      }
    },
    actionName: {
      type: String,
      required: true
    },
    textField: {
      type: [String, Function],
      default: () => ''
    },
    valueField: {
      type: [String, Function],
      default: () => ''
    },
    /** 选择框默认文字 */
    placeholder: {
      type: String,
      default: '请选择'
    },
    /** 是否可以清空选项，只在单选时有效 */
    clearable: {
      type: Boolean,
      default: true
    },
    /** 是否支持多选，默认为false */
    multiple: {
      type: Boolean,
      default: false
    },
    /** 是否支持过滤，默认为true */
    filterable: {
      type: Boolean,
      default: true
    },
    /** 是否禁用，默认为false */
    disabled: {
      type: Boolean,
      default: false
    },
    /** 是否实时更新数据，为true时，每次展开列表时都会请求数据。默认为false */
    realtime: {
      type: Boolean,
      default: false
    },
    /** 是否自动选择，为true时，接收到收据后自动选择第一条。默认为false */
    autoSelect: {
      type: Boolean,
      default: false
    },
    /** 是否自动定义label，默认为false */
    autoLabel: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      select: [],
      items: [],
      loading: false
    };
  },
  methods: {
    queryData() {
      this.loading = true;
      // 是否需要触发change事件
      const needRaiseChange = this.value && this.items.length === 0;
      this.items = [];
      this.$store
        .dispatch(this.actionName, this.params)
        .then(({ data }) => {
          let datas = data.resultData || data;
          datas.forEach(item => {
            this.items.push({
              ...item,
              value: isFunction(this.valueField)
                ? this.valueField(item)
                : item[this.valueField],
              text: isFunction(this.textField)
                ? this.textField(item)
                : item[this.textField]
            });
          });
          if (needRaiseChange) {
            const selectItem = this.items.find(p => p.value === this.value);
            selectItem && this.$emit('change', selectItem);
          }
          this.loading = false;
        })
        .catch(this.$Error);
    },
    onOpenChange(value) {
      if (this.realtime && value) {
        this.queryData();
      }
    }
  },
  mounted() {
    this.queryData();
  },
  watch: {
    select(value) {
      this.$emit('input', value);
      const item = this.items.find(p => p.value === value);
      item && this.$emit('change', item);
    },
    value: {
      immediate: true,
      handler(value) {
        this.select = value;
      }
    }
  }
};
</script>
